﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace PhoneAppCheckSensors
{
    using Microsoft.Devices.Sensors;
    using System.Device.Location;
    using Microsoft.Phone.Controls.Maps;

    public partial class PageCompassVisual : PhoneApplicationPage
    {
        public PageCompassVisual()
        {
            InitializeComponent();
        }

        private Compass mySensor;

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            string isLocationOK;
            NavigationContext.QueryString.TryGetValue("isLocationOK", out isLocationOK);
            if (bool.Parse(isLocationOK))
            {
                cbShowMap.IsEnabled = true;
            }
            else
            {
                cbShowMap.IsEnabled = false;
            }

            mySensor = new Compass();
            mySensor.TimeBetweenUpdates = TimeSpan.FromSeconds(2);
            mySensor.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<CompassReading>>(mySensor_CurrentValueChanged);
            mySensor.Start();

            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            mySensor.Stop();
            mySensor.Dispose();

            if (myWatcher != null)
            {
                myWatcher.Stop();
                myWatcher.PositionChanged -= myWatcher_PositionChanged;
                myWatcher.Dispose();
                myWatcher = null;
            }
            base.OnNavigatedFrom(e);
        }

        private double lastTrueHeading = 0;
        void mySensor_CurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                double durationUnit = 500;
                Duration duration = new Duration(TimeSpan.FromMilliseconds(durationUnit));

                // 反時計回りを考慮
                double trueHeading = 360 - e.SensorReading.TrueHeading;
                tbTrueHeading.Text = String.Format("{0:0.000}", trueHeading);

                Timeline animation = null;
                trueHeading += 180;
                trueHeading %= 360;

                DoubleAnimation dAnimation = new DoubleAnimation();
                dAnimation.By = lastTrueHeading;
                dAnimation.To = trueHeading;
                dAnimation.Duration = duration;
                animation = dAnimation;

                Storyboard sb = new Storyboard();
                sb.Duration = duration;
                sb.Children.Add(animation);
                Storyboard.SetTarget(animation, compassRotation);
                Storyboard.SetTargetProperty(animation, new PropertyPath(RotateTransform.AngleProperty));

                sb.Begin();
                //                compassRotation.Angle = trueHeading;

                lastTrueHeading = trueHeading;
            });
        }

        private GeoCoordinateWatcher myWatcher;

        private void cbShowMap_Checked(object sender, RoutedEventArgs e)
        {
            if (myWatcher == null)
            {
                MessageBox.Show(
@"This page use your current location got from 'Location API' as center of map.
This application doesn't share your location data for external of your device.");
                myWatcher = new GeoCoordinateWatcher();
                myWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(myWatcher_PositionChanged);
            }
            myWatcher.Start();
            DoubleAnimation vAnimation = new DoubleAnimation();
            vAnimation.To = 0.5;
            DoubleAnimation sxAnivation = new DoubleAnimation();
            sxAnivation.To = 0.5;
            DoubleAnimation syAnivation = new DoubleAnimation();
            syAnivation.To = 0.5;
            Duration duration = new Duration(TimeSpan.FromMilliseconds(1000));
            vAnimation.Duration = duration;
            sxAnivation.Duration = duration;
            syAnivation.Duration = duration;

            Storyboard sb = new Storyboard();
            sb.Duration = duration;
            sb.Children.Add(vAnimation);
            sb.Children.Add(sxAnivation);
            sb.Children.Add(syAnivation);

            Storyboard.SetTarget(vAnimation, imageCompass);
            Storyboard.SetTargetProperty(vAnimation, new PropertyPath(Image.OpacityProperty));
            Storyboard.SetTarget(sxAnivation, compassScale);
            Storyboard.SetTargetProperty(sxAnivation, new PropertyPath(ScaleTransform.ScaleXProperty));
            Storyboard.SetTarget(syAnivation, compassScale);
            Storyboard.SetTargetProperty(syAnivation, new PropertyPath(ScaleTransform.ScaleYProperty));

            sb.Begin();

            myMap.Visibility = Visibility.Visible;
        }

        private void myWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                myMap.Center = myWatcher.Position.Location;
            });
        }

        void cbShowMap_Unchecked(object sender, RoutedEventArgs e)
        {
            if (myWatcher != null)
            {
                myWatcher.Stop();
            }
            DoubleAnimation vAnimation = new DoubleAnimation();
            vAnimation.To = 1.0;
            DoubleAnimation sxAnivation = new DoubleAnimation();
            sxAnivation.To = 1.0;
            DoubleAnimation syAnimation = new DoubleAnimation();
            syAnimation.To = 1.0;

            Duration duration = new Duration(TimeSpan.FromMilliseconds(1000));
            vAnimation.Duration = duration;
            sxAnivation.Duration = duration;
            syAnimation.Duration = duration;

            Storyboard sb = new Storyboard();
            sb.Duration = duration;
            sb.Children.Add(vAnimation);
            sb.Children.Add(sxAnivation);
            sb.Children.Add(syAnimation);

            Storyboard.SetTarget(vAnimation, imageCompass);
            Storyboard.SetTargetProperty(vAnimation, new PropertyPath(Image.OpacityProperty));
            Storyboard.SetTarget(sxAnivation, compassScale);
            Storyboard.SetTargetProperty(sxAnivation, new PropertyPath(ScaleTransform.ScaleXProperty));
            Storyboard.SetTarget(syAnimation, compassScale);
            Storyboard.SetTargetProperty(syAnimation, new PropertyPath(ScaleTransform.ScaleYProperty));
            sb.Begin();

            myMap.Visibility = Visibility.Collapsed;
        }
    }
}